viz.sequenceDiagram = (function () {
    function background() {
        return {
            id : "background",
            width : function (graphics) {
                return 0;
            },
            height : function (graphics) {
                return 0;
            },
            draw : function (graphics) {
                graphics.background(0, 96);
            }
        };
    }

    function participant(name) {
        var padding = 1;
        return {
            id : "p:" + name,
            width : function (graphics) {
                return graphics.textWidth(name);
            },
            height : function (graphics) {
                return graphics.textHeight(name);
            },
            draw : function (graphics, localCoordinate) {
                graphics.text(name, localCoordinate.x(0), localCoordinate.y(0), 255);
                graphics.line(localCoordinate.x(0), localCoordinate.y(graphics.textHeight(name)), localCoordinate.x(graphics.textWidth(name)), localCoordinate.y(graphics.textHeight(name)), 255);
            }
        };
    }

    function messageTransfer(id, message) {
        var padding = 1;
        return {
            id : "m:" + id,
            width : function (graphics) {
                return graphics.textWidth(message);
            },
            height : function (graphics) {
                return graphics.textHeight(message);
            },
            draw : function (graphics, localCoordinate) {
                graphics.text(message, localCoordinate.x(0), localCoordinate.y(0), 255);
            }
        };
    }

    function operationExecution(id) {
        return {
            id : "o:" + id,
            width : function (graphics) {

            },
            height : function (graphics) {

            },
            draw : function (graphics, localCoordinate) {

            }
        };
    }

    function statefulParticipant(name) {
        return {
            id : "sp:" + name,
            width : function (graphics) {

            },
            height : function (graphics) {

            },
            draw : function (graphics, localCoordinate) {

            }
        };
    }

    return {
        messageTransfer : function (screen, event) {
            var sender = participant(event.sender);
            var message = messageTransfer(event.sender + "->" + event.receiver, event.message);
            var receiver = participant(event.receiver);

            screen.addFrameAsset(background());
            screen.placeFrameAsset(sender);
            screen.placeFrameAsset(message).after(sender);
            screen.placeFrameAsset(receiver).after(message);

            return {
                firstFrame : function () {
                    // modifies assets so that it represents first frame of this slide
                },
                lastFrame : function () {
                    // modifies assets so that it represents last frame of this slide
                },
                isLastFrame : function () {

                },
                nextFrame : function () {

                }
            };
        },

        stateTransition : function (screen, event) {
            screen.addFrameAsset(background());
            screen.addFrameAsset(participant("wave.wonderland"));
            var operation = screen.addFrameAsset(operationExecution("wave.wonderland->bedtimeStory"));
            var state = screen.addFrameAsset(statefulParticipant("bedtimeStory"));
            return {
                firstFrame : function () {
                    // modifies assets so that it represents first frame of this slide
                },
                lastFrame : function () {
                    // modifies assets so that it represents last frame of this slide
                },
                isLastFrame : function () {

                },
                nextFrame : function () {

                }
            };
        }
    };
})();